﻿using System;
using System.ComponentModel;
using System.Windows;

namespace Monti.Docking
{
   /// <summary>
   /// Requried methods and properties for a dock content object.
   /// </summary>
   public abstract class DockItem : IDockItem
   {
      #region Fields

      /// <summary>
      /// Event used to notify when a property has changed.
      /// </summary>
      public event PropertyChangedEventHandler PropertyChanged;

      private string m_Title;
      private string m_ToolTip;
      private bool m_IsActiveContent;
      private bool m_IsSelected;
      private bool m_AllowClose;
      private bool m_IsEnabled;

      #endregion

      #region Setup

      /// <summary>
      /// Initializes a new dock item. You must set the content property to have a visual in the tab.
      /// </summary>
      protected DockItem ()
      {
         this.AllowClose = true;
         this.m_IsEnabled = true;
      }

      /// <summary>
      /// Initializes a new dock item.
      /// </summary>
      /// <param name="viewType">The view type for the tab item.</param>
      protected DockItem (Type viewType)
      {
         this.AllowClose = true;
         this.m_IsEnabled = true;

         var factory = new FrameworkElementFactory (viewType);
         factory.SetValue (FrameworkElement.DataContextProperty, this);
         this.ContentTemplate = new DataTemplate { VisualTree = factory };
      }

      #endregion

      #region Properties

      /// <summary>
      /// Gets or Sets if the content is selected.
      /// </summary>
      public bool IsSelected
      {
         get { return this.m_IsSelected; }
         set
         {
            this.m_IsSelected = value;
            this.RaisePropertyChanged ("IsSelected");
         }
      }

      /// <summary>
      /// Gets or Sets if the content is the acitve content.
      /// </summary>
      public bool IsActiveContent
      {
         get { return this.m_IsActiveContent; }
         set
         {
            this.m_IsActiveContent = value;
            this.RaisePropertyChanged ("IsActiveContent");
         }
      }

      /// <summary>
      /// Gets or Sets if the content is enabled.
      /// </summary>
      public bool IsEnabled
      {
         get { return this.m_IsEnabled; }
         set
         {
            this.m_IsEnabled = value;
            this.RaisePropertyChanged ("IsEnabled");
         }
      }

      /// <summary>
      /// Gets or Sets if the content can be closed or not.
      /// </summary>
      public bool AllowClose
      {
         get { return this.m_AllowClose; }
         set
         {
            this.m_AllowClose = value;
            this.RaisePropertyChanged ("AllowClose");
         }
      }

      /// <summary>
      /// Gets or Sets the title of the content.
      /// </summary>
      public string Title
      {
         get { return this.m_Title; }
         set
         {
            this.m_Title = value;
            this.RaisePropertyChanged ("Title");
         }
      }

      /// <summary>
      /// Gets or Sets the tool tip text.
      /// </summary>
      public string ToolTip
      {
         get { return this.m_ToolTip; }
         set
         {
            this.m_ToolTip = value;
            this.RaisePropertyChanged ("ToolTip");
         }
      }

      /// <summary>
      /// Gets or Sets the content for the dock item.
      /// </summary>
      public FrameworkElement Content { get; set; }

      /// <summary>
      /// Gets or Sets the template for the dock item's content.
      /// </summary>
      public DataTemplate ContentTemplate { get; set; }

      /// <summary>
      /// Gets the dock group.
      /// </summary>
      public DockGroup DockGroup { get; set; }

      #endregion

      #region Methods

      /// <summary>
      /// Raises the property changed event.
      /// </summary>
      /// <param name="propertyName">Name of property that has changed.</param>
      protected virtual void RaisePropertyChanged (string propertyName)
      {
         if (this.PropertyChanged != null)
            this.PropertyChanged (this, new PropertyChangedEventArgs (propertyName));
      }

      /// <summary>
      /// Performs any closing operations.
      /// </summary>
      /// <returns>True if Ok to close, otherwise false.</returns>
      public virtual bool Closing () { return true; }

      #endregion
   }
}
